package com.radar.algorithm;

import com.radar.common.ProductType;
import com.radar.exception.RadarCaclError;
import com.radar.exception.RadarDecodeError;
import com.radar.exception.RadarVisualizeError;
import com.radar.visualize.RasterMap;
import org.bytedeco.javacpp.indexer.Indexer;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.*;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.NetcdfFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import static org.bytedeco.opencv.global.opencv_video.calcOpticalFlowFarneback;

public class CaclOpenCv {

    public static void main1(String[] args) throws IOException {

        String f1 = "/Users/xx/data/testFlowMask/FY4A-_AGRI--_N_REGC_1047E_L2-_PRD-_MULT_GLL_20201228071500_20201228071917_4000M_VPRJ5_EVB0086_0.png";

        String f2 = "/Users/xx/data/testFlowMask/FY4A-_AGRI--_N_REGC_1047E_L2-_PRD-_MULT_GLL_20201228073418_20201228073835_4000M_VPRJ5_EVB0086_0.png";

        String maskF = "/Users/xx/data/testFlowMask/FY4A_AGRIX_L2_20201228_0715_4000M_PRJ1_cloud_top_height.png";

        // 3, 0.5, @Cast({"bool"}) boolean var3, 15, 3, 5, 1.2, 0
        BufferedImage mask = ImageIO.read(new File(maskF));
        int m = 6579300;
        Mat ff1 = opencv_imgcodecs.imread(f1);
        Mat ff2 = opencv_imgcodecs.imread(f2);
        Mat prvs = ff1.clone();
        Mat next = ff1.clone();
        Mat flow = next.clone();
        opencv_imgproc.cvtColor(ff1, prvs, opencv_imgproc.COLOR_BGR2GRAY);
        opencv_imgproc.cvtColor(ff2, next, opencv_imgproc.COLOR_BGR2GRAY);
        // 计算光流
        calcOpticalFlowFarneback(prvs, next, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
        Indexer indexer = flow.createIndexer();
        Indexer indexerPrecip = next.createIndexer();
        int h = 1226;
        int w = 2001;
        float[][] precip = new float[h][w];
        float[][] u = new float[h][w];
        float[][] v = new float[h][w];
        for (int i = 0; i < h; i ++) {
            for (int j = 0; j < w; j ++) {
                if (j < w - 1 && i < h - 1 && mask.getRGB(j, i) == m) {
                    continue;
                }
                u[i][j] = (float) indexer.getDouble(i, j, 0);
                v[i][j] = (float) indexer.getDouble(i, j, 1);
                precip[i][j] = (float) indexerPrecip.getDouble(i, j);
            }
        }
        SemiLagrangian semiLagrangian = new SemiLagrangian();
        int t = 6;
        float[][][] extrapolate = semiLagrangian.extrapolate(precip, u, v, t);
        for (int i = 0; i < t; i++) {
            BufferedImage bufferedImage = new BufferedImage(2001, 1226, BufferedImage.TYPE_INT_ARGB);
            for (int j = 0; j < 1226; j++) {
                for (int k = 0; k < 2001; k++) {
                    int z = (int) (extrapolate[i][j][k] == Float.NaN ? 0 : extrapolate[i][j][k]);
                    z = z > 255 ? 255 : z;
                    if(z == 0){
                        bufferedImage.setRGB(k, j, m);
                    }else{
                        bufferedImage.setRGB(k, j, new Color(z, z, z).getRGB());
                    }
                }
            }
            ImageIO.write(bufferedImage, "png", new File("/Users/xx/data/java/flow_" + i + ".png"));
        }

//        for (int i = 0; i < h; i += 10) {
//            for (int j = 0; j < w; j += 10) {
//                double x = indexer.getDouble(i, j, 0) * 5;
//                double y = indexer.getDouble(i, j, 1) * 5;
//                Point p0 = new Point(j, i);
//                Point p1 = new Point((int) Math.round(x + j), (int) Math.round(y + i));
//                if (j < w - 1 && i < h - 1 && mask.getRGB(j, i) == m) {
//                    continue;
//                }
//                line(next, p0, p1, RGB(255, 0, 0));
//            }
//        }
//        imwrite("/Users/xx/data/flow.png", next);

    }

    public static void main(String[] args) throws RadarDecodeError, RadarVisualizeError, RadarCaclError, IOException, InvalidRangeException {
//        String c = "/Users/xx/DeskTop/9692/Z_RADR_I_Z9692_20210119060929_O_DOR_CC_CAP_FMT.bin.bz2";
//        CinradRadar radar = new CinradRadar();
//        radar.parse(c);
        RasterMap rasterMap = new RasterMap(null);
//        GridData ppi = radar.radar.getPPI(0, ProductType.REF);
//        BufferedImage bufferedImage = rasterMap.simpleRaster(RasterMap.buildRasterInfo(ProductType.REFGRAY).backColor(new Color(0, 0, 0, 0)), ppi);
//        ImageIO.write(bufferedImage,"png",new File("/Users/xx/DeskTop/pre.png"));
//        radar.dispose();
//
//        c = "/Users/xx/DeskTop/9692/Z_RADR_I_Z9692_20210119060342_O_DOR_CC_CAP_FMT.bin.bz2";
//        radar = new CinradRadar();
//        radar.parse(c);
//        rasterMap = new RasterMap(radar.radar);
//        ppi = radar.radar.getPPI(0, ProductType.REF);
//        bufferedImage = rasterMap.simpleRaster(RasterMap.buildRasterInfo(ProductType.REFGRAY).backColor(new Color(0, 0, 0, 0)), ppi);
//        ImageIO.write(bufferedImage,"png",new File("/Users/xx/DeskTop/next.png"));

        int h = 268;
        int w = 296;
        NetcdfFile pre_nc = NetcdfFile.open("/Users/xx/DeskTop/Z9692_20210119064414_MQPF_20210119064414.nc");
        NetcdfFile next_nc = NetcdfFile.open("/Users/xx/DeskTop/Z9692_20210119065001_MQPF_20210119065001.nc");
        byte[][] d1 = (byte[][]) pre_nc.findVariable("maxReflective").read().copyToNDJavaArray();
        byte[][] d2 = (byte[][]) next_nc.findVariable("maxReflective").read().copyToNDJavaArray();
        BufferedImage b1 = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        BufferedImage b2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        for(int i = 0 ; i < h ; i ++){
            for(int j = 0 ; j < w ; j  ++){
                if(d1[i][j] != -128 && (d1[i][j] * 3.33) + 40 > 5){
                    b1.setRGB(j,i,rasterMap.getColor((d1[i][j] * 3.33) + 40,ProductType.REFGRAY).getRGB());
                }
                if(d2[i][j] != -128 && (d2[i][j] * 3.33) + 40 > 5){
                    b2.setRGB(j,i,rasterMap.getColor((d2[i][j] * 3.33) + 40,ProductType.REFGRAY).getRGB());
                }
            }
        }
        String f1 = "/Users/xx/DeskTop/pre.png";
        String f2 = "/Users/xx/DeskTop/next.png";
        ImageIO.write(b1, "png", new File(f1));
        ImageIO.write(b2, "png", new File(f2));

        System.out.println();
        // 5264 × 4789
        Mat ff1 = opencv_imgcodecs.imread(f1);
        Mat ff2 = opencv_imgcodecs.imread(f2);
        Mat prvs = ff1.clone();
        Mat next = ff1.clone();
        Mat flow = next.clone();
        opencv_imgproc.cvtColor(ff1, prvs, opencv_imgproc.COLOR_BGR2GRAY);
        opencv_imgproc.cvtColor(ff2, next, opencv_imgproc.COLOR_BGR2GRAY);
        // 计算光流
        calcOpticalFlowFarneback(prvs, next, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
        Indexer indexer = flow.createIndexer();
        Indexer indexerPrecip = next.createIndexer();

        float[][] precip = new float[h][w];
        float[][] u = new float[h][w];
        float[][] v = new float[h][w];
        for (int i = 0; i < h; i ++) {
            for (int j = 0; j < w; j ++) {
                u[i][j] = (float) indexer.getDouble(i, j, 0);
                v[i][j] = (float) indexer.getDouble(i, j, 1);
                precip[i][j] = (float) indexerPrecip.getDouble(i, j);
            }
        }
        SemiLagrangian semiLagrangian = new SemiLagrangian();
        int t = 24;
        float[][][] extrapolate = semiLagrangian.extrapolate(precip, u, v, t);
        for (int i = 0; i < t; i++) {
            BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            for (int j = 0; j < h; j++) {
                for (int k = 0; k < w; k++) {
                    int z = (int) (extrapolate[i][j][k] == Float.NaN ? 0 : extrapolate[i][j][k]);
                    bufferedImage.setRGB(k, j, new Color(z, z, z).getRGB());
                }
            }
            ImageIO.write(bufferedImage, "png", new File("/Users/xx/data/java/flow_" + i + ".png"));
        }
    }
}
